#include "CancellableTimer.h"

#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN  0x0
#define LOG_TAG     "CancellableTimer"
#include <hilog/log.h>


namespace {
constexpr bool DEBUG = false;
}

CancellableTimer::CancellableTimer(int32_t delayMs, std::function<void ()> &&fn) : CancellableTimer("", delayMs, std::move(fn)) {
}

CancellableTimer::CancellableTimer(const std::string_view name, int32_t delayMs, std::function<void()> &&fn) : name(name) {
    timer = std::async(std::launch::async, [=, this, fn=std::move(fn)] {
        std::unique_lock l(mtx);
        if (cancelCond.wait_for(l, std::chrono::milliseconds{delayMs}) == std::cv_status::timeout) {
            if constexpr (DEBUG) {
                OH_LOG_DEBUG(LOG_APP, "timer %{public}s scheduling on timeout", this->name.c_str());
            }
            fn();
        } else {
            if constexpr (DEBUG) {
                OH_LOG_DEBUG(LOG_APP, "timer %{public}s cancelled", this->name.c_str());
            }
        }
    });
    if constexpr (DEBUG) {
        OH_LOG_DEBUG(LOG_APP, "timer %{public}s started with delay %{public}d ms", this->name.c_str(), delayMs);
    }
}

CancellableTimer::~CancellableTimer() {
    cancelCond.notify_one();
    timer.wait();
}
